    package com.binc.testspring.common.lamada;

    import com.binc.testspring.common.lamada.pojo.Color;
    import org.junit.Test;

    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.function.Function;
    import java.util.function.Predicate;
    import java.util.stream.Collectors;

    public class StreamDistinctTest {

        public static void main(String[] args) {
            List<Color> list= new ArrayList<>();
            list.add(new Color(5, "DogA5"));
            list.add(new Color(5, "DogA5_2"));
            list.add(new Color(4, "DogA4"));
            list.add(new Color(6, "DogA6"));
            List<Color> collect = list.stream().distinct().collect(Collectors.toList());
            System.out.println(collect);




            // 按整个个对象去重
            System.out.println("整个对象去重：");
            list.stream().distinct()
                    .forEach(System.out::println);

            // 指定某个字段去重
            System.out.println("指定age属性去重（方法一）：");
            list.stream().filter(distinctByKey1(s -> s.getNum()))
                    .forEach(System.out::println);

            // 方法二（用循环)
            System.out.println("指定age属性去重（方法二）：");
            TreeSet<Color> colors = new TreeSet<>(Comparator.comparing(s -> s.getNum()));  // 这是利用了treeset的不可重复特性，定制了比较方法，如果num属性一致就默认他是相同对象；
            for (Color color : list) {
                colors.add(color);
            }
            new ArrayList<>(colors)
                    .forEach(System.out::println);


            // 方法三：（是方法二的变形），此方法来源于：https://blog.csdn.net/qq_28988969/article/details/81119587
            // collectingAndThen的作用是先将list流中的数据收集到treeSet中（利用treeset的去重特性），然后将treeset的结果再转成List集合；
            System.out.println("指定age属性去重（方法三）：");
            list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getNum()))), ArrayList::new))
                    .forEach(System.out::println);

            //这里是将流中数据收集到treeset中
            System.out.println("指定age属性去重（方法三）：");
            TreeSet<Color> collect1 = list.stream().collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getNum()))));
            TreeSet<Color> collect12 = list.stream().collect(Collectors.toCollection(() -> new TreeSet<>()));
            System.out.println(collect12);
            System.out.println(collect1);


        }

        @Test
        public void test(){
          TreeSet<Integer>   ts  = new TreeSet<>();
          ts.add(1);
          ts.add(2);
          ts.add(1);
            System.out.println(ts);

        }


        // 次方法来源于：https://blog.csdn.net/haiyoung/article/details/80934467
        static <T> Predicate<T> distinctByKey1(Function<? super T, ?> keyExtractor) {
            Map<Object, Boolean> seen = new ConcurrentHashMap<>();
            return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
        }
    }
